package com.hedl.classroom.service.jobhandle;

import com.hedl.classroom.base.exception.OnlinecClassroomException;
import com.hedl.classroom.feignclient.CourseIndex;
import com.hedl.classroom.feignclient.SearchServiceClient;
import com.hedl.classroom.mapper.CoursePublishMapper;
import com.hedl.classroom.model.dto.CoursePreviewDto;
import com.hedl.classroom.model.po.CoursePublish;
import com.hedl.classroom.model.po.MqMessage;
import com.hedl.classroom.service.CoursePublishService;
import com.hedl.classroom.service.MessageProcessAbstract;
import com.hedl.classroom.service.MqMessageService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;

/**
 * ProjectName: onlinec-classroom
 * DateTime: 2023/7/28 17:41
 * Author: Big Watermelon
 * Description: 课程发布的任务类
 */
@Slf4j
@Component
public class CoursePublishTask extends MessageProcessAbstract {

    @Resource
    private CoursePublishService coursePublishService;

    @Resource
    private SearchServiceClient searchServiceClient;

    @Resource
    private CoursePublishMapper coursePublishMapper;

    @XxlJob("coursePublishJobHandler")
    public void coursePublishJobHandler()throws Exception{
        // 分片参数
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();
        log.info("当前分片：{},总分片：{}",shardIndex,shardTotal);

        //调用抽象类的方法执行任务
        process(shardIndex,shardTotal,"course_publish",30,60);
    }

    /**
     * Description: 执行课程发布的逻辑，如果此方法抛出异常说明执行任务失败
     * @param mqMessage 执行任务内容
     * @return
     */
    @Override
    public boolean execute(MqMessage mqMessage) {
        //从MqMessage拿到课程id
        Long courseId = Long.parseLong(mqMessage.getBusinessKey1());

        //课程静态化上传到minio
        generateCourseHtml(mqMessage,courseId);
        //向elasticsearch写索引数据
        saveCourseIndex(mqMessage,courseId);
        //向redis写缓存



        //返回true表示任务完成
        return true;
    }

    //生成课程静态化页面并上传至文件系统
    private void generateCourseHtml(MqMessage mqMessage,long courseId){
        //消息id
        Long taskId = mqMessage.getId();
        MqMessageService mqMessageService = this.getMqMessageService();

        //做任务的幂等性处理
        //取出该阶段执行状态
        int stageOne = mqMessageService.getStageOne(taskId);
        if (stageOne > 0) {
            log.debug("课程静态化完成，无需处理...");
            return ;
        }

        //int a = 1/0;

        //开始课程静态化 生成html页面
        File file = coursePublishService.generateCourseHtml(courseId);
        if (file == null){
            OnlinecClassroomException.cast("课程静态化异常!");
        }

        //将html上传到minio
        coursePublishService.uploadCourseHtml(courseId,file);

        //任务处理完成写任务处理完成
        mqMessageService.completedStageOne(taskId);
    }

    //保存课程索引信息
    private void saveCourseIndex(MqMessage mqMessage,long courseId){
        //消息id
        Long taskId = mqMessage.getId();
        MqMessageService mqMessageService = this.getMqMessageService();
        //取出第二阶段的状态
        int stageTwo = mqMessageService.getStageTwo(taskId);

        //任务幂等性处理
        if (stageTwo > 0) {
            log.debug("课程索引信息以写入，无需处理...");
            return ;
        }
        //查询课程信息，调用搜索服务添加索引
        CoursePublish coursePublish = coursePublishMapper.selectById(courseId);
        CourseIndex courseIndex = new CourseIndex();
        BeanUtils.copyProperties(coursePublish,courseIndex);
        //远程调用
        Boolean add = searchServiceClient.add(courseIndex);
        if (!add){
            OnlinecClassroomException.cast("远程调用搜索服务添加课程索引失败！");
        }

        //完成本阶段的任务
        mqMessageService.completedStageTwo(taskId);
    }
}
